﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Reflection;

namespace DataEntity.XMLSchema
{
    public class xml_BaseClass
    {
        /// <summary>        
        /// 数据表转换成员值
        /// </summary>
        public void SetValues(DataRow drReceive)
        {
            // 如果表格的行数为0，则表示该实体没有初始化，IsEmpty=true
            if (drReceive == null) { return; }

            // 枚举实体类属性,把接受的datatable中的数据赋給根据类属性架构的datatable
            foreach (DataColumn column in drReceive.Table.Columns)
            {
                string columnName = column.ColumnName;
                FieldInfo property = this.GetType().GetField(columnName);

                if (property != null && drReceive[columnName] != DBNull.Value)
                {
                    property.SetValue(this, Convert.ChangeType(drReceive[columnName], property.FieldType));
                }
            }
        }

        /// <summary>        
        /// 数据表转换成员值
        /// </summary>
        public static List<IXmlBase> SetArrayOfValues<IXmlBase>(DataTable dt) where IXmlBase: new ()
        {
            if (dt == null || dt.Rows.Count == 0) { return default(List<IXmlBase>); }

            List<IXmlBase> ixbs = new List<IXmlBase>();
            //循环表行
            foreach (DataRow dr in dt.Rows)
            {
                IXmlBase xb = new IXmlBase();
                MethodInfo mi = xb.GetType().GetMethod("SetValues", new Type[] { typeof(DataRow) });
                if (mi != null) 
                { 
                    mi.Invoke(xb, new object[] { dr });
                    ixbs.Add(xb);
                }//调用该方法
            }

            return ixbs;
        }

        /// <summary>
        /// 成员值转换成与数据库同步的实体类
        /// </summary>
        public IEntity GetDataEntity<IEntity>() where IEntity : new()
        {
            IEntity iobj = new IEntity();

            foreach (PropertyInfo pi in iobj.GetType().GetProperties())
            {
                string columnName = pi.Name;
                FieldInfo fi = this.GetType().GetField(columnName);
                if (fi != null)
                {
                    try
                    {
                        pi.SetValue(iobj, Convert.ChangeType(fi.GetValue(this), pi.PropertyType), null);
                    }
                    catch { }
                }
            }

            return iobj;
        }

        /// <summary>
        /// 返回该对象的XML数据
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns>成功.XML 空记录.None 失败.Failed</returns>
        public string GetXml(DataTable dt)
        {
            try
            {
                if (dt == null || dt.Rows.Count == 0) { return "None"; }
                this.SetValues(dt.Rows[0]);
                return new TXIO.XML_IO().SaveToText(this);
            }
            catch { return "Failed"; }
        }

        /// <summary>
        /// 返回该对象集合的XML数据
        /// </summary>
        /// <typeparam name="IXmlBase">对象类型</typeparam>
        /// <param name="dt">数据表</param>
        /// <returns>成功.XML 空记录.None 失败.Failed</returns>
        public static string GetArrayOfXml<IXmlBase>(DataTable dt) where IXmlBase : new()
        {
            try
            {                
                if (dt == null || dt.Rows.Count == 0) { return "None"; }
                List<IXmlBase> xmls = new List<IXmlBase>();

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    IXmlBase ixml = new IXmlBase();
                    MethodInfo mi = ixml.GetType().GetMethod("SetValues", new Type[]{ typeof(DataRow) });
                    if (mi != null) { mi.Invoke(ixml, new object[] { dt.Rows[i] }); }//调用该方法                    
                    xmls.Add(ixml);
                }
                return new TXIO.XML_IO().SaveToText((object)xmls);
            }
            catch { return "Failed"; }
        }

        /// <summary>
        /// xml转实体类
        /// </summary>
        /// <typeparam name="IXmlBase">对象类型</typeparam>
        /// <param name="xmlContent">xml内容</param>
        /// <returns>[成功] 对象实例 [失败] null</returns>
        public static IXmlBase LoadXml<IXmlBase>(string xmlContent)
        {
            try {
                return (IXmlBase)new TXIO.XML_IO().LoadFromText(typeof(IXmlBase), xmlContent);
            }
            catch { return default(IXmlBase); }
        }

        /// <summary>
        /// xml转实体类数组
        /// </summary>
        /// <typeparam name="IXmlBase">对象类型</typeparam>
        /// <param name="xmlContent">xml内容</param>
        /// <returns>[成功] 对象实例数组 [失败] null</returns>
        public static List<IXmlBase> LoadArrayOfXml<IXmlBase>(string xmlContent) where IXmlBase : new()
        {
            try
            {
                return (List<IXmlBase>)new TXIO.XML_IO().LoadFromText(typeof(List<IXmlBase>), xmlContent);
            }
            catch { return default(List<IXmlBase>); }
        }

        /// <summary>
        /// 对象集合转数据表
        /// </summary>
        /// <typeparam name="IXmlBase">对象类型</typeparam>
        /// <param name="xmlContent">xml内容</param>
        /// <returns>数据表</returns>
        public static DataTable ArrayToTable<IXmlBase>(List<IXmlBase> ixbs) where IXmlBase : new()
        {          
            if (ixbs == null) { return null; }

            DataTable dt = new DataTable();
            IXmlBase ixb = new IXmlBase();
            MethodInfo mi = ixb.GetType().GetMethod("GetDataTableSchema");
            if (mi != null) { dt = (DataTable)mi.Invoke(ixb, null); }//调用该方法

            //循环插入数据
            foreach (IXmlBase t in ixbs)
            {
                DataRow dr = dt.NewRow();
                //循环字段
                foreach (DataColumn dc in dt.Columns)
                {
                    FieldInfo fi = t.GetType().GetField(dc.ColumnName);
                    if (fi != null)
                    {
                        dr[dc.ColumnName] = Convert.ChangeType(fi.GetValue(t), dc.DataType);
                    }
                }

                dt.Rows.Add(dr);
            }
            return dt;
        }

        /// <summary>
        /// Xml转数据表
        /// </summary>
        /// <typeparam name="IXmlBase">对象类型</typeparam>
        /// <param name="xmlContent">xml内容</param>
        /// <returns>数据表</returns>
        public static DataTable XmlToTable<IXmlBase>(string xmlContent) where IXmlBase : new()
        {            
            List<IXmlBase> ixbs = LoadArrayOfXml<IXmlBase>(xmlContent);

            return ArrayToTable<IXmlBase>(ixbs);
        }

        /// <summary>
        /// 获取对象的表结构
        /// </summary>
        /// <returns>有结构的空表</returns>
        public DataTable GetDataTableSchema()
        {
            DataTable dt = new DataTable(this.GetType().Name);
            
            //循环对象的公共成员
            foreach (FieldInfo fi in this.GetType().GetFields())
            {
                try
                {
                    DataColumn dc = new DataColumn(fi.Name, fi.FieldType);
                    dt.Columns.Add(dc);
                }
                catch { }
            }
            return dt.Clone();
        }
    }
}
